﻿using NetCoreCMS.IServices;
using NetCoreCMS.Models;
using Newtonsoft.Json;
using StackExchange.Redis;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace NetCoreCMS.Web.Areas.WebApi.Controllers
{
    public class ShopGeoHelper
    {
        private static List<Shop> GetAll(int cid, string redisName,IShopService _shop)
        {
            using (ConnectionMultiplexer redis = ConnectionMultiplexer.Connect("localhost:6379"))
            {
                IDatabase db = redis.GetDatabase();
                string json = db.StringGet(redisName + "shopgeo");
                if (!string.IsNullOrEmpty(json) && json != "[]")//不为空 开始反序列化
                {
                    try
                    {
                        List<Shop> config = JsonConvert.DeserializeObject<List<Shop>>(json);
                        if (cid > 0)
                            config = config.Where(a => a.category_id == cid).ToList();
                        return config;
                    }
                    catch (Exception)//反序失败就查
                    {
                        string strwhere = "where is_pass=1 and is_lock=0";
                        if (cid > 0)
                            strwhere = strwhere + " and category_id=" + cid;
                        List<Shop> config = _shop.GetList(1, 10000, strwhere, "sort_id desc,id desc");
                        json = JsonConvert.SerializeObject(config);
                        db.StringSet(redisName + "shopgeo", json, new TimeSpan(7200 * TimeSpan.TicksPerSecond));
                        //更新geo
                        for (int i = 0; i < config.Count; i++)
                        {
                            db.GeoRemove(redisName + "location", redisName + "shopgeo_" + config[i].id);
                            db.GeoAdd(redisName + "location", config[i].longitude, config[i].latitude, redisName + "shopgeo_" + config[i].id);
                        }
                        if (cid > 0)
                            config = config.Where(a => a.category_id == cid).ToList();
                        return config;
                    }
                }
                else//为空，查，序列化,存;
                {
                    string strwhere = "where is_pass=1 and is_lock=0";
                    if (cid > 0)
                        strwhere = strwhere + " and category_id=" + cid;
                    List<Shop> config = _shop.GetList(1, 10000, strwhere, "sort_id desc,id desc");
                    json = JsonConvert.SerializeObject(config);
                    db.StringSet(redisName + "shopgeo", json, new TimeSpan(7200 * TimeSpan.TicksPerSecond));
                    //更新geo
                    for (int i = 0; i < config.Count; i++)
                    {
                        db.GeoRemove(redisName + "location", "shopgeo_" + config[i].id);
                        db.GeoAdd(redisName + "location", config[i].longitude, config[i].latitude, redisName + "shopgeo_" + config[i].id);
                    }
                    if (cid > 0)
                        config = config.Where(a => a.category_id == cid).ToList();
                    return config;
                }
            }
        }
        /// <summary>
        /// 根据我的位置查出附近的商家(腾讯高德：31.7575372817,116.5484941006)
        /// </summary>
        /// <param name="longitude">我的经度</param>
        /// <param name="latitude">我的纬度</param>
        /// <param name="distance">距离之内</param>
        /// <param name="count">最大数量</param>
        /// <returns></returns>
        public static GeoRadiusResult[] GetGEO(double longitude, double latitude, double distance, int count, int cid ,string redisName, IShopService _shop)
        {
            List<Shop> list = new List<Shop>();
            using (ConnectionMultiplexer redis = ConnectionMultiplexer.Connect("localhost:6379"))
            {
                var all = GetAll(cid,redisName,_shop);
                IDatabase db = redis.GetDatabase();
                var result = db.GeoRadius(redisName + "location", longitude, latitude, distance, GeoUnit.Kilometers, count, null, GeoRadiusOptions.WithDistance);
                return result;
            }
        }
    }
}
